import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPProxy
{
    private String host;
    private Socket clientSoc;
    
    private static final int BUFFER_SIZE = 1024; 
    
    public TCPProxy(String host, Socket clientSoc)
    {
        this.host = host;
        this.clientSoc = clientSoc;
    }
    
    public void run()
    {
        try
        {
            while (true)
            {
                Socket cnSoc = new Socket(host, clientSoc.getLocalPort());
                
                new Thread(new Forwarder(cnSoc, clientSoc)).start();
                new Thread(new Forwarder(clientSoc, cnSoc)).start();
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    private class Forwarder implements Runnable
    {
        private Socket src;
        private Socket dst;
        
        public Forwarder(Socket src, Socket dst)
        {
            this.src = src;
            this.dst = dst;
        }

        @Override
        public void run()
        {
            BufferedInputStream in = null;
            BufferedOutputStream out = null;
            try
            {
                in = new BufferedInputStream(src.getInputStream());
                out = new BufferedOutputStream(dst.getOutputStream());
                
                byte[] buffer = new byte[BUFFER_SIZE];
                
                int n;
                while ((n = in.read(buffer)) != -1)
                {
                    out.write(buffer, 0, n);
                    out.flush();
                }
            }
            catch (IOException e)
            {
            }
            finally
            {
                try
                {
                    in.close();
                    out.close();
                    src.close();
                    dst.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
